#ifndef __LOGGER_H__
#define __LOGGER_H__
 
#include <string>
#include <memory>
#include <thread>
#include <mutex>
#include <functional>
#include <condition_variable>
#include <list>
#include <iostream>
#include <sstream>
//struct FILE;
 
enum LOG_LEVEL{
    LOG_INFO,
    LOG_DEBUG,
    LOG_ERROR,
    LOG_DEFUALT
};

#define LogInfo(...)        Logger::getInstance().AddToQueue("INFO", __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__)
#define LogDebug(...)     Logger::getInstance().AddToQueue("DEBUG", __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__)
#define LogError(...)       Logger::getInstance().AddToQueue("ERROR", __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__)
 
class Logger
{
public:
    static Logger& getInstance();
    bool Init(const char* filename);
    void setFileName(const char* filename);
    void setPrint(bool isprint = true);
    bool Start();
    void Finish();
 
    void AddToQueue(const char* pszLevel, const char* pszFile, int lineNo, const char* pszFuncSig,const char* pszFmt, ...);
private:
    Logger() = default;
    Logger(const Logger& rhs) = delete;
    Logger& operator =(Logger& rhs) = delete;
    void threadfunc();
 
private:
    std::string                     filename_;
    FILE*                           fp_{};
    std::shared_ptr<std::thread>    spthread_;
    std::mutex                      mutex_;
    std::condition_variable         cv_;            //有新的日志到来的标识
    bool                            exit_{false};
    std::list<std::string>          queue_;
    bool                            print_{true};    
};
 
#endif //!__LOGGER_H__